#region Copyright RenGuiYou. All rights reserved.
//=====================================================
// NeatlyFrameWork
// Author:      RenGuiyou
// Feedback: 	mailto:750539605@qq.com
//=====================================================
#endregion

using System.Linq;
using Neatly.UI;
using NeatlyEditor.UI;
using UnityEditor;
using UnityEngine;
using UnityEditor.AnimatedValues;

namespace NeatlyEditor
{
    [CustomEditor(typeof(NImage), true)]
    [CanEditMultipleObjects]
    public class NImageEditor : NImageBaseEditor
    {
        SerializedProperty m_AdaptSceneTop;
        SerializedProperty m_SupportRtl;
        SerializedProperty m_Type;
        SerializedProperty m_FillMethod;
        SerializedProperty m_FillOrigin;
        SerializedProperty m_FillAmount;
        SerializedProperty m_FillClockwise;
        SerializedProperty m_FillCenter;
        SerializedProperty m_GradientEnable;
        SerializedProperty m_GradientStartColor;
        SerializedProperty m_GradientEndColor;

        GUIContent m_AdaptSceneTopContent;
        GUIContent m_SupportRtlContent;
        GUIContent m_SpriteTypeContent;
        GUIContent m_ClockwiseContent;
        GUIContent m_GradientContent;

        AnimBool m_ShowSlicedOrTiled;
        AnimBool m_ShowSliced;
        AnimBool m_ShowFilled;
        AnimBool m_ShowType;

        protected override void OnEnable()
        {
            base.OnEnable();

            m_AdaptSceneTopContent = new GUIContent("适配全面屏顶部");
            m_SupportRtlContent = new GUIContent("支持国际化图片翻转");
            m_SpriteTypeContent = new GUIContent("Image Type");
            m_ClockwiseContent = new GUIContent("Clockwise");
            m_GradientContent = new GUIContent("渐变模式");
            
            m_AdaptSceneTop = serializedObject.FindProperty("m_AdaptSceneTop");
            m_SupportRtl = serializedObject.FindProperty("m_SupportRtl");
            m_Type = serializedObject.FindProperty("m_Type");
            m_FillCenter = serializedObject.FindProperty("m_FillCenter");
            m_FillMethod = serializedObject.FindProperty("m_FillMethod");
            m_FillOrigin = serializedObject.FindProperty("m_FillOrigin");
            m_FillClockwise = serializedObject.FindProperty("m_FillClockwise");
            m_FillAmount = serializedObject.FindProperty("m_FillAmount");
            m_GradientEnable = serializedObject.FindProperty("m_GradientEnable");
            m_GradientStartColor = serializedObject.FindProperty("m_GradientStartColor");
            m_GradientEndColor = serializedObject.FindProperty("m_GradientEndColor");

            var typeEnum = (NImage.Type)m_Type.enumValueIndex;

            m_ShowType = new AnimBool(m_Sprite.objectReferenceValue != null);
            m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == NImage.Type.Sliced);
            m_ShowSliced = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == NImage.Type.Sliced);
            m_ShowFilled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == NImage.Type.Filled);

            m_ShowType.valueChanged.AddListener(Repaint);
            m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint);
            m_ShowSliced.valueChanged.AddListener(Repaint);
            m_ShowFilled.valueChanged.AddListener(Repaint);

            SetShowNativeSize(true);
        }

        protected override void OnDisable()
        {
            m_ShowType.valueChanged.RemoveListener(Repaint);
            m_ShowSlicedOrTiled.valueChanged.RemoveListener(Repaint);
            m_ShowSliced.valueChanged.RemoveListener(Repaint);
            m_ShowFilled.valueChanged.RemoveListener(Repaint);
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            EditorGUILayout.PropertyField(m_AdaptSceneTop, m_AdaptSceneTopContent);
            EditorGUILayout.PropertyField(m_SupportRtl, m_SupportRtlContent);
            SpriteGUI();
            AppearanceControlsGUI();
            RaycastControlsGUI();
            UseSpritePackerGUI();
            OnGradientGUI();

            if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded))
                TypeGUI();
            EditorGUILayout.EndFadeGroup();

            SetShowNativeSize(false);

            NImage image = target as NImage;

            if (image.sprite != null && (image.sprite.border.w < 0 || image.sprite.border.x < 0 ||
                                         image.sprite.border.y < 0 || image.sprite.border.z < 0))
            {
                EditorGUILayout.HelpBox("The Image have a error border.", MessageType.Error);
            }

            NativeSizeButtonGUI();
            if (image.UseSpritePacker)
            {
                EditorGUILayout.HelpBox("当前非TP模式，请记得修改.", MessageType.Info);
            }

            serializedObject.ApplyModifiedProperties();
        }

        protected override void SpriteGUI()
        {
            EditorGUI.BeginChangeCheck();
            base.SpriteGUI();
            if (EditorGUI.EndChangeCheck())
            {
                var newSprite = m_Sprite.objectReferenceValue as Sprite;
                if (newSprite)
                {
                    NImage.Type oldType = (NImage.Type)m_Type.enumValueIndex;
                    if (newSprite.border.SqrMagnitude() > 0)
                    {
                        m_Type.enumValueIndex = (int)NImage.Type.Sliced;
                    }
                    else if (oldType == NImage.Type.Sliced)
                    {
                        m_Type.enumValueIndex = (int)NImage.Type.Simple;
                    }
                }
            }
        }

        void SetShowNativeSize(bool instant)
        {
            SetShowNativeSize(true, instant);
        }

        protected void TypeGUI()
        {
            EditorGUILayout.PropertyField(m_Type, m_SpriteTypeContent);
            ++EditorGUI.indentLevel;
            {
                NImage.Type typeEnum = (NImage.Type)m_Type.enumValueIndex;

                bool showSlicedOrTiled = (!m_Type.hasMultipleDifferentValues &&
                                          (typeEnum == NImage.Type.Sliced || typeEnum == NImage.Type.Tiled));
                if (showSlicedOrTiled && targets.Length > 1)
                    showSlicedOrTiled = targets.Select(obj => obj as NImage).All(img => img.hasBorder);

                m_ShowSlicedOrTiled.target = showSlicedOrTiled;
                m_ShowSliced.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues &&
                                       typeEnum == NImage.Type.Sliced);
                m_ShowFilled.target = (!m_Type.hasMultipleDifferentValues && typeEnum == NImage.Type.Filled);

                NImage image = target as NImage;
                if (EditorGUILayout.BeginFadeGroup(m_ShowSlicedOrTiled.faded))
                {
                    if (image.hasBorder)
                        EditorGUILayout.PropertyField(m_FillCenter);
                }

                EditorGUILayout.EndFadeGroup();

                if (EditorGUILayout.BeginFadeGroup(m_ShowSliced.faded))
                {
                    if (image.sprite != null && !image.hasBorder)
                    {
                        EditorGUILayout.HelpBox("The Image doesn't have a border.", MessageType.Error);
                    }
                }

                EditorGUILayout.EndFadeGroup();

                if (EditorGUILayout.BeginFadeGroup(m_ShowFilled.faded))
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(m_FillMethod);
                    if (EditorGUI.EndChangeCheck())
                    {
                        m_FillOrigin.intValue = 0;
                    }

                    switch ((NImage.FillMethod)m_FillMethod.enumValueIndex)
                    {
                        case NImage.FillMethod.Horizontal:
                            m_FillOrigin.intValue =
                                (int)(NImage.OriginHorizontal)EditorGUILayout.EnumPopup("Fill Origin",
                                    (NImage.OriginHorizontal)m_FillOrigin.intValue);
                            break;
                        case NImage.FillMethod.Vertical:
                            m_FillOrigin.intValue =
                                (int)(NImage.OriginVertical)EditorGUILayout.EnumPopup("Fill Origin",
                                    (NImage.OriginVertical)m_FillOrigin.intValue);
                            break;
                        case NImage.FillMethod.Radial90:
                            m_FillOrigin.intValue =
                                (int)(NImage.Origin90)EditorGUILayout.EnumPopup("Fill Origin",
                                    (NImage.Origin90)m_FillOrigin.intValue);
                            break;
                        case NImage.FillMethod.Radial180:
                            m_FillOrigin.intValue = (int)(NImage.Origin180)EditorGUILayout.EnumPopup("Fill Origin",
                                (NImage.Origin180)m_FillOrigin.intValue);
                            break;
                        case NImage.FillMethod.Radial360:
                            m_FillOrigin.intValue = (int)(NImage.Origin360)EditorGUILayout.EnumPopup("Fill Origin",
                                (NImage.Origin360)m_FillOrigin.intValue);
                            break;
                    }

                    EditorGUILayout.PropertyField(m_FillAmount);
                    if ((NImage.FillMethod)m_FillMethod.enumValueIndex > NImage.FillMethod.Vertical)
                    {
                        EditorGUILayout.PropertyField(m_FillClockwise, m_ClockwiseContent);
                    }
                }

                EditorGUILayout.EndFadeGroup();
            }
            --EditorGUI.indentLevel;
        }

        public override bool HasPreviewGUI()
        {
            return true;
        }

        public override void OnPreviewGUI(Rect rect, GUIStyle background)
        {
            NImage image = target as NImage;
            if (image == null) return;

            Sprite sf = image.sprite;
            if (sf == null) return;

            SpriteDrawUtility.DrawSprite(sf, rect, image.canvasRenderer.GetColor());
        }

        public override string GetInfoString()
        {
            NImage image = target as NImage;
            Sprite sprite = image.sprite;

            int x = (sprite != null) ? Mathf.RoundToInt(sprite.rect.width) : 0;
            int y = (sprite != null) ? Mathf.RoundToInt(sprite.rect.height) : 0;

            return string.Format("Image Size: {0}x{1}", x, y);
        }

        private void OnGradientGUI()
        {
            EditorGUILayout.PropertyField(m_GradientEnable, m_GradientContent);
            if (m_GradientEnable.boolValue)
            {
                ++EditorGUI.indentLevel;
                EditorGUILayout.PropertyField(m_GradientStartColor);
                EditorGUILayout.PropertyField(m_GradientEndColor);
                --EditorGUI.indentLevel;
            }
        }
    }
}